package com.tbit.uqbike.client.service.impl;

import com.alibaba.fastjson.JSON;
import com.tbit.common.constant.*;
import com.tbit.common.entity.ArrearsLog;
import com.tbit.common.entity.BalanceChange;
import com.tbit.common.entity.UserAccountMoney;
import com.tbit.common.entity.UserCapitalChange;
import com.tbit.uqbike.client.constant.UserConstant;
import com.tbit.uqbike.client.dao.core.UserAccountMoneyDao;
import com.tbit.uqbike.client.pojo.RideLog;
import com.tbit.uqbike.client.pojo.RideLogDetails;
import com.tbit.uqbike.client.pojo.User;
import com.tbit.uqbike.client.service.PushMsgLogService;
import com.tbit.uqbike.client.service.RideLogService;
import com.tbit.uqbike.client.service.UserAccountMoneyService;
import com.tbit.uqbike.client.service.UserToAgentService;
import com.tbit.uqbike.client.util.DateTimeUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * @Author: chen
 * @Description: 用户区域余额
 * @Date: 创建于 14:13 2022/11/23
 */
@Service
@Slf4j
public class UserAccountMoneyServiceImpl implements UserAccountMoneyService {

    @Autowired
    private UserAccountMoneyDao userAccountMoneyDao;
    @Autowired
    private PushMsgLogService pushMsgLogService;
    @Autowired
    private UserToAgentService userToAgentService;
    @Autowired
    private RideLogService rideLogService;

    @Override
    public void insert(User user, Long money, Integer moneyType, Integer accountId, Integer patType) {
        UserAccountMoney userAccountMoney = getByAccountId(user.getUserId(), moneyType, accountId);
        if (userAccountMoney == null) {
            userAccountMoney = new UserAccountMoney(user.getUserId(), user.getPhone(), accountId, user.getAccountId(), money, System.currentTimeMillis()
                    , moneyType, "");
            userAccountMoneyDao.insert(userAccountMoney);
        } else {
            if (patType.equals(PayPlatformContent.PAY_USE)) {
                money = -money;
            }
            log.warn("用户" + user.getUserId() + "修改前" + userAccountMoney.getMoney() + "修改后" + money);
            UserAccountMoney userAccountMoneyDB = new UserAccountMoney();
            userAccountMoneyDB.setMoney(money);
            userAccountMoneyDB.setMoneyType(moneyType);
            userAccountMoneyDB.setAccountId(accountId);
            userAccountMoneyDB.setUpdateTime(System.currentTimeMillis());
            userAccountMoneyDB.setUserId(user.getUserId());
            userAccountMoneyDao.edit(userAccountMoneyDB);
        }
    }

    @Override
    public void editRideMoney(Integer brandId, Integer accountId, Long dateTime, Integer userId) {
        userAccountMoneyDao.editRideMoney(userId, BalanceLogChangeTypeContent.capitalType_arrearsLog, dateTime);
    }

    @Override
    public void editMoney(User user, String orderNO, Long money, Integer moneyType,
                          Integer accountId, Integer patType, Long dateTime, String remark, Integer businessType) {
        UserAccountMoney userAccountMoney = getByAccountId(user.getUserId(), moneyType, accountId);

        if (patType.equals(PayPlatformContent.PAY_RECHARGE)) {
            insert(user, money, moneyType, accountId, patType);
        } else {
            /**区域余额不足支付*/
            if (userAccountMoney == null || userAccountMoney.getMoney() < money) {
                if (userAccountMoney != null && userAccountMoney.getMoney() > 0) {
                    /**将区域余额扣完*/
                    money = money - userAccountMoney.getMoney();
                    addLog(user, orderNO, userAccountMoney.getMoney(), moneyType, accountId
                            , patType, userAccountMoney.getMoney(), 0L, dateTime, remark, accountId, businessType);
                }
                /**在扣除其他区域金额*/
                List<UserAccountMoney> monies = getByUserIdAndBrandId(user.getUserId(), moneyType);
                Long totalMoney = money;
                if (!monies.isEmpty()) {
                    for (UserAccountMoney userAccountMoneyDB : monies) {
                        if (userAccountMoneyDB.getAccountId().equals(accountId) || userAccountMoneyDB.getMoney() <= 0) {
                            continue;
                        }
                        /**扣费*/
                        if (userAccountMoneyDB.getMoney() >= totalMoney) {
                            addLog(user, orderNO, totalMoney, moneyType, userAccountMoneyDB.getAccountId(), patType, userAccountMoneyDB.getMoney()
                                    , userAccountMoneyDB.getMoney() - totalMoney, dateTime, remark, accountId, businessType);
                            totalMoney = 0L;
                        } else {
                            addLog(user, orderNO, userAccountMoneyDB.getMoney(), moneyType, userAccountMoneyDB.getAccountId(), patType, userAccountMoneyDB.getMoney()
                                    , 0L, dateTime, remark, accountId, businessType);
                            totalMoney = totalMoney - userAccountMoneyDB.getMoney();
                        }
                        if (totalMoney <= 0) {
                            break;
                        }
                    }
                }
                if (totalMoney > 0) {
                    log.info("用户未知区域余额" + user.getUserId());
                }
            } else {
                addLog(user, orderNO, money, moneyType, accountId, patType, userAccountMoney.getMoney(),
                        userAccountMoney.getMoney() - money, dateTime, remark, accountId, businessType);
            }
        }

    }

    /**
     * 添加日志
     *
     * @param user
     * @param orderNO
     * @param money
     * @param moneyType
     * @param accountId
     * @param patType
     */
    public void addLog(User user, String orderNO, Long money, Integer moneyType,
                       Integer accountId, Integer patType, Long changeStartMoney, Long changeEndMoney
            , Long dateTime, String remark, Integer oldId, Integer businessType) {
        //Integer businessType= getBusinessType(patType,moneyType);
        insert(user, money, moneyType, accountId, patType);
        /**如果用户是在区域外充值余额，用户金额变动区域使用订单的区域*/
        if (Objects.equals(accountId, -1)){
            RideLog rideLog = rideLogService.getByOrderNO(orderNO);
            accountId = rideLog.getAccountId();
        }
        addUserCapitalChange(user, accountId, orderNO, moneyType, businessType, remark, oldId, money, patType, changeStartMoney, changeEndMoney
                , dateTime);
        addBalanceChange(user, accountId, orderNO, changeStartMoney, money, changeEndMoney, dateTime, remark, moneyType, businessType
                , patType);
    }


    public Integer getBusinessType(Integer patType, Integer moneyType) {
        Integer businessType = BusinessConstant.BUSINESS_USER_RECHARGE_BALANCE;
        if (patType.equals(PayPlatformContent.PAY_USE) && moneyType.equals(PayPlatformContent.PAY_BALANCE)) {
            businessType = BusinessConstant.BUSINESS_BALANCE_OF_CYCLING;
        } else if (patType.equals(PayPlatformContent.PAY_USE) && moneyType.equals(PayPlatformContent.PAY_DEPOSIT)) {
            businessType = BusinessConstant.BUSINESS_USER_REFUND_DEPOSIT;
        } else if (patType.equals(PayPlatformContent.PAY_USE) && moneyType.equals(PayPlatformContent.PAY_GIFCARD)) {
            businessType = BusinessConstant.BUSINESS_RIDE_USE_GIF;
        } else if (patType.equals(PayPlatformContent.PAY_RECHARGE) && moneyType.equals(PayPlatformContent.PAY_BALANCE)) {
            businessType = BusinessConstant.BUSINESS_USER_RECHARGE_BALANCE;
        } else if (patType.equals(PayPlatformContent.PAY_RECHARGE) && moneyType.equals(PayPlatformContent.PAY_DEPOSIT)) {
            businessType = BusinessConstant.BUSINESS_USER_DEPOSIT;
        } else if (patType.equals(PayPlatformContent.PAY_RECHARGE) && moneyType.equals(PayPlatformContent.PAY_GIFCARD)) {
            businessType = BusinessConstant.BUSINESS_RECHARGE_GIF_GIVE;
        }
        return businessType;
    }

    /**
     * 用户区域余额变动
     *
     * @param user              用户信息
     * @param accountId         区域id
     * @param orderNO           订单编号
     * @param capitalType       金额类型
     * @param businessType      交易类型
     * @param remark            备注
     * @param originalAccountId 源区域id
     * @param cashMoney         变动金额
     */
    public void addUserCapitalChange(User user, Integer accountId, String orderNO, Integer capitalType, Integer businessType
            , String remark, Integer originalAccountId, Long cashMoney, Integer patType, Long changeStartMoney, Long changeEndMoney, Long dateTime) {
        UserCapitalChange userCapitalChange = new UserCapitalChange(user.getUserId(), user.getPhone(), user.getName(), accountId,
                user.getAccountId(), changeStartMoney, cashMoney, changeEndMoney, patType, capitalType,
                businessType, orderNO, null, null, null,
                orderNO, orderNO, dateTime,
                remark, originalAccountId);
        pushMsgLogService.sendPushLog(JSON.toJSONString(userCapitalChange), TableNameConstant.USERCAPITALCHANGE);
    }

    public void addBalanceChange(User user, Integer accountId, String orderNO, Long changeStartMoney
            , Long changeMoney, Long changeEndMoney, Long dateTime, String remark, Integer capitalType, Integer businessType, Integer patType) {
        BalanceChange balanceChange = new BalanceChange(user.getUserId(), user.getPhone(), user.getName(), accountId
                , user.getAccountId(), changeStartMoney, changeMoney
                , changeEndMoney, patType
                , capitalType, businessType
                , dateTime, remark, orderNO);
        pushMsgLogService.sendPushLog(JSON.toJSONString(balanceChange), TableNameConstant.BALANCECHANGE);
    }


    @Override
    public UserAccountMoney getByAccountId(Integer userId, Integer moneyType, Integer accountId) {
        Map<String, Object> map = new HashMap<>();
        map.put("userId", userId);
        map.put("moneyType", moneyType);
        map.put("accountId", accountId);
        return userAccountMoneyDao.getByAccountId(map);
    }

    @Override
    public List<UserAccountMoney> getByUserIdAndBrandId(Integer userId, Integer moneyType) {
        Map<String, Object> map = new HashMap<>();
        map.put("userId", userId);
        map.put("moneyType", moneyType);
        return userAccountMoneyDao.getByUserIdAndBrandId(map);
    }

    @Override
    public void del(Integer userId, Integer moneyType, Integer accountId) {
        UserAccountMoney userAccountMoney = new UserAccountMoney();
        userAccountMoney.setUserId(userId);
        userAccountMoney.setMoneyType(moneyType);
        userAccountMoney.setAccountId(accountId);
        userAccountMoneyDao.del(userAccountMoney);
    }

    @Override
    public void updateRideMoney(Long afterRideMoney, Long endMoney, Integer userId, Integer accountId, Long updateTime, User user, RideLogDetails rideLogDetails) {
        userAccountMoneyDao.updateRideMoney(userId, accountId, endMoney, updateTime);
        String billingDetails = rideLogDetails.getBillingDetails();
        String changeRemark = billingDetails == null ? "" : billingDetails.substring(billingDetails.lastIndexOf(",") + 1);
        ArrearsLog arrearsLog = new ArrearsLog(user.getUserId(), user.getPhone(), user.getName(), accountId, user.getAccountId()
                , rideLogDetails.getAccountName(), rideLogDetails.getOrderId(), ArrearsLogContent.PAY, ArrearsLogContent.MANUALLY_MODIFY_ORDER_REPLENISHMENT
                , afterRideMoney.intValue() - endMoney.intValue(), afterRideMoney.intValue(), endMoney.intValue(), updateTime, rideLogDetails.getOrderId(), UserConstant.USER_ADMIN
                , "系统管理员", "用户使用卡券抵扣欠款", changeRemark);
        log.info("{}日志推送:{}", changeRemark, arrearsLog);
        pushMsgLogService.sendPushLog(JSON.toJSONString(arrearsLog), TableNameConstant.ARREARSLOG);
    }
}
